#include "iConfig.hpp"
#include <glf/task/taskManager.h>
#include <glf/task/taskCondition.h>

namespace glf {

TaskManager::TaskManager()
	: m_WorkStatus(0)
	, m_ExecuteImmediately(false)
	, m_TasksPause(false)
	, m_ConcurrentTasksQueue(16)
{
}

TaskManager::~TaskManager()
{
	GLF_ASSERT(m_ConcurrentTasksQueue.Size() == 0);
}

void TaskManager::Push(Task* task, bool signal)
{
	m_ConcurrentTasksQueue.Push(task);
	if(signal)
	{
		Signal();
	}
}

void TaskManager::Signal()
{
	SpinLockScope lock(m_SpinMutex);
	for(TaskConditionList::iterator i = m_TaskConditionList.begin(), 
			end = m_TaskConditionList.end(); 
		i != end; 
		++i)
	{
		if((*i)->Signal())
		{
			break;
		}
	}
}

void TaskManager::Broadcast()
{
	SpinLockScope lock(m_SpinMutex);
	for(TaskConditionList::iterator i = m_TaskConditionList.begin(), 
		end = m_TaskConditionList.end(); 
		i != end; 
	++i)
	{
		(*i)->Signal();
	}
}

Task* TaskManager::Pop()
{
	if(m_TasksPause)
	{
		return NULL;
	}

	Task* task = NULL;
	m_ConcurrentTasksQueue.TryPop(task);

	return task;
}

void TaskManager::AddTaskCondition(TaskCondition* tc)
{
	SpinLockScope lock(m_SpinMutex);
	m_TaskConditionList.push_back(tc);
}

void TaskManager::RemoveTaskCondition(TaskCondition* tc)
{
	SpinLockScope lock(m_SpinMutex);
	m_TaskConditionList.remove(tc);
}

} // end namespace glf
